<?php
// +----------------------------------------------------------------------
// | Bwsaas
// +----------------------------------------------------------------------
// | Copyright (c) 2015~2020 http://www.buwangyun.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Gitee ( https://gitee.com/buwangyun/bwsaas )
// +----------------------------------------------------------------------
// | Author: buwangyun <hnlg666@163.com>
// +----------------------------------------------------------------------
// | Date: 2020-9-28 10:55:00
// +----------------------------------------------------------------------

namespace buwang\service\cloud;

use app\common\model\cloud\Service;
use app\common\model\cloud\Wallet;
use app\Request;
use buwang\exception\CloudException;
use buwang\traits\ErrorTrait;
use buwang\traits\TransTrait;

class Cloud
{
    //租户id
    protected $member_id;

    use ErrorTrait;
    use TransTrait;

    public function __construct(Request $request)
    {
        if (!isset(app()->bwRequest)) throw new CloudException('未获取到租户id');

        //member后台获取顶级租户member_id
        if (app('bwRequest')->scopes() == 'member') $this->member_id = app('bwRequest')->userInfo()->top_id;
        //admin后台不能使用云服务
        elseif (app('bwRequest')->scopes() == 'admin') throw new CloudException('总平台暂时无法使用云服务');
        //TODO 其他登录类型需要根据应用id获取顶级租户member_id
        else throw new CloudException('租户id获取尚未完善');
    }

    /**
     * 调用云服务
     * @param string $file_name
     * @param array $params
     * @return bool
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function run(string $file_name, array $params)
    {
        $className = "\\buwang\\service\\cloud\\{$file_name}";
        //服务类是否存在
        if (!class_exists($className)) return self::setError('服务不存在');

        //实例化云市场服务类
        $cloudService = new $className();
        //服务类是否存在run方法
        if (!method_exists($cloudService, 'run')) return self::setError('服务中不存在run方法');

        //服务是否已安装
        $service = Service::where(['file_name' => $file_name])->find();
        if (!$service) return self::setError('服务尚未开放');

        //验证参数
        $tempParam = explode(',', $service['params']);
        foreach ($tempParam as $v) {
            if (!isset($params[$v])) return self::setError("缺少参数【{$v}】");
        }

        //查询该租户 该服务 是否有剩余次数
        $amount = Wallet::where(['member_id' => $this->member_id, 'service_id' => $service['id']])->value('amount') ?: 0;
        if ($amount <= 0) return self::setError("【{$service['name']}】服务已无剩余次数");

        //调用服务
        $res = $cloudService->run($params);
        if (!$res) return self::setError($cloudService->getError());

        self::beginTrans();
        try {
            $res = Wallet::changeAmount($this->member_id, $service['id'], 'use', -1, '调用服务');
            if (!$res) {
                self::rollbackTrans();
                return self::setError(\app\common\model\member\Wallet::getError());
            }

            self::commitTrans();
        } catch (\Exception $e) {
            self::rollbackTrans();
            return self::setError($e->getMessage());
        }

        return $res;
    }
}